Core.Storage.DaoProxy = function(ctx, storage, observable) {
	Core.Storage.DaoProxy.superclass.constructor.call(this, ctx, storage, observable);
};

Env.extend(Core.Storage.DaoProxy, Core.Storage.ValueResolver, {
	
	/**
	 * Creates deffered dao expression.
	 * Return value will enable to get & set the given path from the underlying storage.
	 */
	createDao: function(path) {
		return Core.Storage.Dao.create(this, path);
	},
	
	/**
	 * Sets the value into global storage.
	 * Accepts multilevel dao expression if it points to the global storage.
	 * Will throw an error if the path points to the configuration storage primitive.
	 * 
	 * @param String path
	 * @param Any value
	 */
	set: function(raw, value) {
		var path = this.pathr.evaluate(raw);
		
		if(/^\.\./.test(path)) { Core.Storage.set(path.substr(2), value); return; }
		if(/^\./.test(path)) { this._setLocally(path.substr(1), value); return; }

		throw new Error("Path '"+ path +"' does not have any leading dots.");
	},
	
	/**
	 * Sets the value into global storage using local dao expression.
	 * 
	 * @param String path - trimmed out of dots local path.
	 * @param Any value
	 */
	_setLocally: function(path, value) {
		var head = path.shift("."),
			tail = path.substr(head.length),
			dao = this.storage.get(head);
	
		Core.assert(Lang.isDao(dao), "Can't perform setting on non-dao property.");
		dao.set.call(this.ctx, value, tail);
	},
	
	/**
	 * Evaluates the value into final variable.
	 * Handles primitives, dao expression & function-like values.

	 * @param Any v - value
	 * @param Boolean fe - force to evaluate type:"function" if set to true.
	 * @param String tail - value subpath or null.
	 */
	evaluate: function(v, fe, tail) {
		if(Lang.isDao(v)) { return this.evaluate(v.get.call(this.ctx, "." + tail)); }
		else { return Core.Storage.DaoProxy.superclass.evaluate.call(this, v, fe, tail); }
	}
});